perm filename PLAYX.FAI[MUS,LCS]1 blob
sn#057032 filedate 1974-01-08 generic text, type T, neo UTF8
00100 TITLE BUFFER; DOROTHY BENDER ****** GARPLY *******
00200
00300 ; ROUTINE TO READ THE OUTPUT FROM THE MUSIC
00400 ; PROGRAM AND CALL THE D-A CONVERTER TO PLAY.
00500 ;
00600 ; THE NAME OF THE FILE TO BE INPUTTED IS 'MUSIC',
00700 ; THE FIRST RECORD OF WHICH CONTAINS THE
00800 ; NUMBER OF WORDS OF DATA IN THE ENTIRE DISK FILE.
00900
00910 EXTERNAL CORGET,FSINIT
01000 A ← 1 ;WORK
01100 B ← 2 ;WORK
01110 P←17
01120 BLOCK←4
01130 SIZE←5
01200 RET ← 3 ;RETURN ACCUMULATOR
01210 PLN←20
01220 PDL: BLOCK PLN
01240
01300 ;;BUFSIZ ←=20224
01400 ↓DSKCHN ←1 ;DISK CHANNEL FOR INPUT
01500 ↓ADCHN ←2 ;D-A CHANNEL FOR OUTPUT
01600
01700 OPDEF READCH [51B8]
01800 OPDEF MESSAGE[51B8!3B12]
01900
02000 BEG: CALLI 0,0 ;RESET I/O DEVICES
02010 MOVE P,[IOWD PLN,PDL]
02020 PUSHJ P,FSINIT
02030 MOVEI SIZE1←=20224
02040 PUSHJ P,CORGET
02050 HALT,
02060 SUBI BLOCK,1
02070 MOVEM BLOCK, LOOP+1
02080
02090 PUSHJ P,CORGET
02100 HALT,
02110 SUBI BLOCK,1
02120 MOVEM BLOCK, LOOP+4
02130
02190 OPEN DSKCHN,[17 ;MODE
02200 'DSK ' ;DEVICE NAME
02300 0] ;NO BUFFER HEADERS
02400 HALT BEG ;RESTART IF DEVICE IS UNAVAILABLE
02500
02600 SETZM FILBLK+3 ;FOR RESTART
02700 SETZM FILBL2+3 ;FOR RESTART
02800 LX: MESSAGE [ASCIZ/
02900 TYPE `P' TO PLAY FROM DISK, `C' TO COPY TAPE TO DISK.
03000 /]
03100 readch a
03200 cain a,"C"
03300 jrst start
03400 caie a,"P"
03500 jrst lx
03600 skipe filblk+3 ;is this first time through ?
03700 jrst pla2 ;No. Parameters already set up.
03800 ;FIND OUT NUMBER OF CHANNELS AND
03900 ;THE SPEED.
04000
04100 MESSAGE [ASCIZ/HOW MANY CHANNELS?/]
04200 READCH A
04300 SUBI A,"0"+1 ;CONVERT TO BINR AND ADD 1
04400 DPB A,[POINT 2,OUTBIT,26]
04500
04600 MESSAGE [ASCIZ/WHAT IS THE SPEED?/]
04700 READCH A
04800 SUBI A,"0"
04900 DPB A,[POINT 3,OUTBIT,32]
05000
05100 PLA2: SETZM FILBLK+3
05200 SETZM FILBL2+3
05300 LOOKUP DSKCHN,FILBLK
05400 SKIPA ;CAN'T FIND MUSIC.MUS
05500 JRST XOPEN ;FOUND IT
05600 LOOKUP DSKCHN,FILBL2 ;TRY FOR MUSAA.DMD
05700
05800 JRST [MESSAGE[ASCIZ/
05900 *** MUSIC FILE NOT FOUND/]
06000 CALLI 12]
06100 ;EXIT IF FILE IS MISSING
06200 MOVE A,FILBL2+3 ;GET LENGTH OF MUSAA.DMD
06300 MOVEM A,FILBLK+3;PUT IT IN RIGHT PLACE
06400
06500 XOPEN: OPEN ADCHN,[117 ;MODE
06600 'AD ' ;DEVICE NAME
06700 0] ;NO BUFFER HEADERS
06800
06900 JRST [MESSAGE[ASCIZ/
07000 ***D-A NOT AVAILABLE/]
07100 CALLI 12]
07200 ;EXIT IF D-A IS UNAVAILABLE
07300
07400 SPWAR: SPCWAR 17,[CALLI]
07500 MESSAGE [ASCIZ/ GO? /]
07600 READCH A
07700
07800
07900 LNTH: movs a,filblk+3 ;get length of file.
08000 movnm a,nwd
08100
08200 ; -----------------------------------------
08300
08400 ;BEGIN MAIN BODY OF PROGRAM
08500
08600 LOOP: JSP RET,SUB ;ROUTINE TO READ AND WRITE
08700 ;; BUF1-1 ;USE BUF1 FOR THE I/O
08710 0
08800 JUMPLE B,OUT ;DONE
08900
09000 JSP RET,SUB ;CALL IT AGAIN
09100 ;; BUF2-1 ;USE BUF2 FOR THE I/O
09110 0
09200 JUMPG B,LOOP ;GO BACK FOR MORE IF B>0
09300
09400 OUT: close dskchn, ;END OF PROGRAM.
09500 releas adchn,
09600 SPCWAR 0,'SSW'
09700 jrst lx
09800
09900 ;SUBROUTINE TO SET UP IOWD AND READ AND WRITE.
10000 ; 1(RET) WILL BE THE RETURN
10100 ; 0(RET) WILL BE THE ADDRESS OF THE BUFFER TO BE
10200 ; PUT IN THE RIGHT HALF OF THE IOWD.
10300 ; A WILL BE A WORK REGISTER
10400 ; B WILL BE TESTED ON THE OUTSIDE.
10500
10600 SUB: MOVNI A,BUFSIZ ;PICK UP AND COMPLEMENT BUFSIZ
10700 ADDB A,NWD ;A←NWD-BUFSIZ
10800 ;NWD←NWD-BUFSIZ
10900 MOVE B,A ;SAVE B TO BE TESTED FOR LAST
11000 ;TIME.
11100 JUMPL A,LAST ;SET UP FOR LAST TIME.
11200 MOVEI A,0
11300
11400 ;THE IOWD LOOKS LIKE:
11500 ; [-BUFSIZ / BUFI-1]
11600
11700 LAST: ADDI A,BUFSIZ
11800 MOVNS A ;COMPLEMENT A
11900 HRL A,0(RET) ;PICK UP BUFI AND MOVE IT
12000 ;TO THE LEFT SIDE OF A.
12100 MOVSM A,INLIST ;SWAP A AND MOVE IT.
12200 MOVSM A,OUTWC ;SAME FOR OUTPUT.
12300 INPUT DSKCHN,INLIST ;READ A RECORD.
12400 OUTPUT ADCHN,OUTWC ;WRITE THE RECORD.
12500 JRST 1(RET) ;RETURN
12600
12700 ; -----------------------------------------
12800
12900 ; STORAGE:
13000
13100 NWD: 0 ;FOR NUMBER OF WORDS OF INPUT.
13200 ;;↓BUF1: BLOCK BUFSIZ+1 ;BUFFER 1
13300 ;;BUF2: BLOCK BUFSIZ+1 ;BUFFER 2
13400
13500 FILBLK: 'MUSIC ' ;FILENAME FOR INPUT
13600 'MUS ' ;EXTENSION
13700 0 ;INFORMATION ON FILE
13800 0 ;PROJECT PROG#
13900
14000 FILBL2: 'MUSAA ' ;FILENAME FOR INPUT, 2ND CHOICE
14100 'DMD ' ;EXTENSION
14200 0 ;INFORMATION ON FILE
14300 0 ;PROJECT PROG#
14400
14500 CLIST: IOWD 1,NWD ;FOR THE FIRST RECORD
14600 0
14700
14800 INLIST: 0 ;WILL CONTAIN AN IOWD
14900 0
15000
15100 OUTWC: 0 ;WILL CONTAIN AN IOWD FOR D-A
15200 3650 ;MAGIC BITS FOR 136.
15300 OUTBIT: 4000 ;BITS FOR D-A
15400 BLOCK 2
15500
15600 begin magdsk
15700
15800 A←1
15900 B←2
16000 D←3
16100 OLNG←=2432 ;size of mag tape records. must be multiple of =128.
16200
16300 ILNG←=2432
16400 ichn←adchn
16500 ochn←dskchn
16600 ↑START: CALLI 0
16700 INIT ICHN,3B28+17
16800 SIXBIT /MTA0/
16900 0
17000 HALT
17100 MTAPE ICHN,1 ;REWIND THE TAPE
17200 JFCL
17300 INIT OCHN,17
17400 SIXBIT /DSK/
17500 0
17600 HALT
17700 ENTER OCHN,[SIXBIT /MUSIC/
17800 SIXBIT /MUS/
17900 0
18000 0]
18100 HALT
18200 loop:input ichn,olst
18300 statz ichn,20000
18400 jrst out ;end of tape.
18500 output ochn,olst
18600 jrst loop
18700 OLST: IOWD OLNG,OBUF
18800 0
18900 obuf←← buf1
19000 bend magdsk
19100
19200 end beg
20000 ENTRY CORGET,CORREL,FSINIT
20010 TITLE CORGET
20020 INTERNAL FSINIT,CORGET,CORREL
20030 EXTERNAL JOBREL,JOBSA,JOBFF,JOBDDT,JOBSYM
20040
20050 THIS←2
20060 SIZ←3
20070 NEXT←4
20080 PREV←5
20090 LAST←6
20100 USER←7
20110 TEMP←10
20120 P←17
20130
20140 INTEGER TOP,FRELST,LOWC
20150 TRIVIAL←←5
20160 ARRAY BUFACS[20]
20170
20180 DEFINE TERPRI(A) <
20190 PUSHJ P,[
20200 OUTSTR [ASCIZ /A
20210 /]
20220 JRST 4,CPOPJ]
20230 >
20240
20250 DEFINE ERR(A) <
20260 OUTSTR [ASCIZ /A
20270 /]
20280 >
21000 ; UTILITY ROUTINES. SAVE AND GET ACCUMULATORS
21010
21020 FSINIT: MOVEI TEMP,-1 ;FOR MAX CORE
21030 MOVEM TEMP,JOBFF ; IS DOING
21040 HLRZ USER,JOBSA
21050 SKIPN JOBDDT ;IF DDT IS IN CORE,
21060 JRST NODDT ; MAKE SURE ITS SYMBOLS ARE PROTECTED
21070 HRRZ TEMP,JOBSYM ;IF JOBSYM IS BELOW JOBFF, THEN
21080 CAML TEMP,USER ; ASSUME ALL SYMBOLS ARE BELOW.
21090 TERPRI <YOUR SYMBOLS ARE SOON TO BE OBLITERATED>
21100
21110
21120 NODDT: SETZM FRELST ; CLEAR POINTERS
21130 SETZM TOP
21140 MOVEI THIS,(USER)
21150 MOVEM THIS,LOWC ; SET BOTTOM OF CORE
21160 PUSHJ P,NEWBLK ;MAKE NEW AREA INTO A FREE BLOCK
21170 JRST JUSTSAVE ;SAVE ACS
21180
21190 NEWBLK:
21200 HRRZ LAST,JOBREL ;END OF BIG BLOCK
21210 NEWB1: SETZM (THIS) ;POINTERS WORD IN BIG BLOCK
21220 ADDI LAST,1 ;CONFORM TO "LAST" STANDARDS
21230 MOVEM LAST,TOP ;TOP OF FREE SPACE
21240 PUSH P,SIZ ;SAVE SIZE
21250 MOVE SIZ,LAST ;COMPUTE SIZE OF NEW BLOCK
21260 SUB SIZ,THIS ;SIZE OF BIG BLOCK
21270 PUSHJ P,RELINK ;PUT ON FREE STORAGE LIST
21280 POP P,SIZ ;GET SIZ BACK
21290 CPOPJ: POPJ P,
21300
21310
21320 JUSTSAVE:
21330 MOVEM TEMP,BUFACS+TEMP
21340 MOVEI TEMP,BUFACS
21350 BLT TEMP,BUFACS+LAST
21360 POPJ P,
21370
21380 BUFRST: MOVSI TEMP,BUFACS
21390 BLT TEMP,TEMP
21400 POPJ P,
23000 ; ROUTINES TO LINK AND UNLINK A BLOCK INTO THE FREE LIST
23010 ; CALL WITH ADDRESS IN THIS AND SIZE IN SIZ
23020
23030 UNLINK:
23040 HRRZ NEXT,(THIS) ;→NEXT BLOCK
23050 HLRZ PREV,(THIS) ;→PREVIOUS BLOCK
23060 SKIPN PREV ;IF A PREV BLOCK DOES NOT EXIST,
23070 MOVEI PREV,FRELST ; USE FRELST POINTER
23080 HRRM NEXT,(PREV) ;CHANGE ITS NEXT FIELD
23090 SKIPE NEXT ;IF A NEXT BLOCK EXISTS,
23100 HRLM PREV,(NEXT) ; CHANGE ITS PREV FIELD
23110 POPJ P, ;BLOCK IN "THIS" IS NO LONGER ON FRELST
23120
23130 RELINK:
23140 HRRZM THIS,-1(LAST) ;X-BIT ← 0, RH ← PTR TO HEAD
23150 MOVEM SIZ,1(THIS) ;GREATER 0 SIZE FIELD ⊃ FREE BLOCK
23160 SKIPE NEXT,FRELST ;PLACE NEW BLOCK ON FRONT OF FRELST
23170 HRLM THIS,(NEXT) ; IF THERE IS ONE
23180 HRRZM NEXT,(THIS) ;POINT TO NEXT FROM THIS
23190 HRRZM THIS,FRELST ;UPDATE FRELST POINTER
23200 POPJ P, ;RETURN
25000 ; ROUTINE TO GET CORE
25010 ; CALL WITH SIZE IN AC 3
25020 ; RETURNS BLOCK IN 2
25030 ; SAVES ALL ACCUMULATORS
25040
25050 CORGET:
25060 PUSHJ P,JUSTSAV ;SAVE AC'S, INITIALIZE WORLD PERHAPS
25070
25080
25090 COR21: ADDI SIZ,3 ;3 WORDS FOR CONTROL INFO
25100 MOVEI THIS,FRELST ;THIS WILL POINT TO THE FIRST GOOD BLOCK
25110
25120 GETLUP: HRRZ THIS,(THIS) ;→NEXT FREE BLOCK
25130 JUMPE THIS,EXPAND ;TRY TO EXPAND CORE, NONE EXIST YET
25140 CAMLE SIZ,1(THIS) ;WILL IT FIT?
25150 JRST GETLUP ; NO, TRY NEXT
25160
25170 GETCOR: AOS (P) ;SUCCESS GUARANTEED
25180 HRRZM THIS,BUFACS+THIS ;RESULT(ALMOST)
25190 PUSHJ P,UNLINK ;UNLINK THIS BLOCK
25200 MOVE LAST,1(THIS) ;REAL BLOCK SIZE
25210 CAIGE LAST,TRIVIAL(SIZ) ;IS DIFFERENCE NEGLIGIBLE?
25220 JRST [MOVSI TEMP,400000 ;YES, USE WHOLE THING --
25230 ADD LAST,THIS ; MARK X-BIT TO INDICATE IN USE
25240 HLLM TEMP,-1(LAST)
25250 JRST GETOUT] ;AND GO FINISH OUT
25260
25270 MOVEM SIZ,1(THIS) ;NEW SIZE FOR RESULT
25280 HRRZ TEMP,THIS ;SAVE START OF BLOCK (RESULT)
25290 ADD THIS,SIZ ;NEW START FOR REMAINING FREE STUFF
25300 SUB LAST,SIZ ;NEW SIZE FOR REMAINS
25310 MOVE SIZ,LAST
25320 ADD LAST,THIS ;NEW END FOR REMAINS
25330 HRLI TEMP,400000 ;TURN X-BIT ON
25340 MOVEM TEMP,-1(THIS) ;IN USER'S BRAND NEW BLOCK
25350 PUSHJ P,RELINK ;RELINK REMAINS, RESTORE ACS
25360
25370
25380 GETOUT: PUSHJ P,BUFRST ;RESTORE ACS
25390 SETZM (THIS) ;PTR RETRIEVED FROM STORAGE
25400 MOVNS 1(THIS) ;SIZE NEG ⊃ IN USE
25410 ADDI THIS,2 ;USER DOESN'T SEE THIS HEADER
25420 POPJ P, ;HERE'S YOUR BLOCK!
27000 ; HERE WE INCREASE THE JOB CORE SIZE
27010
27020 EXPAND: PUSH P,SIZ ;SAVE TOTAL SIZE
27030 HRRZ THIS,TOP ;THIS→NEW BLOCK IF NEXT LOWER IS USED
27040 SKIPGE -1(THIS) ;IS TOP BLOCK FREE?
27050 JRST GETMOR ; NO, USE WHAT YOU HAVE
27060 HRRZ THIS,-1(THIS) ;UNLINK THE
27070 PUSHJ P,UNLINK ; TOP BLOCK
27080
27090 GETMOR: MOVE TEMP,THIS
27100 ADDI TEMP,=1024(SIZ) ;GET MORE AND THEN SOME
27110 POP P,SIZ ;GET THIS BACK BEFORE YOU FORGET
27120 CALL TEMP,[SIXBIT /CORE/] ;ASK FOR MORE
27130 JRST BUFRST ;CAN'T GET IT
27140 PUSHJ P,NEWBLK ;MAKE TOP LOOK LIKE FREE BLOCK
27150 CAMLE SIZ,1(THIS) ;NOW SHOULD FIT
27160 ERR <DRYROT -- EXPAND CODE GLUBBED UP>
27170 JRST GETCOR
28000 ; ROUTINE TO RELEASE CORE, ENTER WITH BLOCK ADDRESS IN 2
28010
28020 CORREL:
28030 PUSHJ P,JUSTSAVE ;SAVE ACS
28040
28050 ; MERGE WITH LOWER NEIGHBOR (ADDRESS-WISE) IF POSSIBLE
28060
28070 SUBI THIS,2 ;USER THINKS IT STARTED 2 PAST
28080 MOVN SIZ,1(THIS) ;SIZE OF THIS BLOCK
28090 MOVE LAST,SIZ ;ADDRESS OF UPPER
28100 ADD LAST,THIS ; NEIGHBOR
28110
28120 CAMGE THIS,LOWC ;IS ADDRESS IN RANGE?
28130 ERR <DRYROT -- BAD ADDRESS TO BUFREL>
28140 CAME THIS,LOWC ;CAN THERE BE A LOWER BLOCK
28150 SKIPGE -1(THIS) ; AND IF SO, IS IT FREE?
28160 JRST UPPET ; NO, LOOK FOR UPPER BLOCK
28170
28180 HRRZ THIS,-1(THIS) ;→LOWER BLOCK
28190 PUSHJ P,UNLINK ;UNLINK IT FROM LIST
28200 ADD SIZ,1(THIS) ;INCREASE SIZE
28210
28220 ; MERGE WITH UPPER NEIGHBOR IF POSSIBLE
28230
28240 UPPET: CAMLE LAST,TOP
28250 ERR <YOU ARE ABOUT TO GET AN ILL MEM-REF>
28260
28270 CAME LAST,TOP ;IS THERE AN UPPER BLOCK?
28280 SKIPGE 1(LAST) ;AND IF SO, IS IT FREE?
28290 JRST LNKRET ; NO, RELINK AND GO AWAY
28300
28310 UPPR: PUSH P,THIS
28320 HRRZ THIS,LAST ;THIS → UPPER NEIGHBOR
28330 PUSHJ P,UNLINK ;GET IT OUT
28340 ADD LAST,1(THIS) ; INCREASE EXTENT
28350 ADD SIZ,1(THIS) ; AND TOTAL SIZE
28360 POP P,THIS ; GET HEADER POINTER BACK
29000 ; HERE WE TRY TO SHRINK CORE
29010
29020 LNKRET:
29030 CAMG LAST,JOBREL ;THIS IS THE LAST CORE BLOCK, AND
29040 JRST LNKRT
29050 CAIGE SIZ,=2046 ; IT IS MORE THAN 2K LONG,
29060 JRST LNKRT
29070 MOVEI TEMP,=2046(THIS) ;THEN 1) SHRINK CORE TO 2K FOR LAST BLOCK
29080 CALL TEMP,[SIXBIT /CORE/]
29090 ERR <DRYROT --CORSER&LNKRET>
29100 MOVE LAST,JOBREL ; AND 2) ADJUST BLOCK TO INDICATE
29110 ADDI LAST,1
29120 MOVEM LAST,TOP ;AND RECORD NEW RESULTS.
29130 MOVE SIZ,LAST ;THE CHANGE BEFORE RELINKING
29140 SUB SIZ,THIS
29150 LNKRT:
29160 PUSHJ P,RELINK ;PUT IT BACK
29170 JRST BUFRST ;AND GO AWAY
29180
29190 END